home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 743 < prev    next >
Encoding:
Text File  |  1996-08-05  |  4.5 KB  |  128 lines

  1. Path: mail2news.demon.co.uk!genesis.demon.co.uk
  2. From: Lawrence Kirby <fred@genesis.demon.co.uk>
  3. Newsgroups: comp.lang.c,comp.unix.programmer,comp.databases
  4. Subject: Re: Aligning struct fields with NDBM (was: Casting unsigned short ...)
  5. Date: Mon, 08 Jan 96 23:01:11 GMT
  6. Organization: none
  7. Message-ID: <821142071snz@genesis.demon.co.uk>
  8. References: <simmons.820857453@rzdspc1> <simmons.821116795@rzdspc1>
  9. Reply-To: fred@genesis.demon.co.uk
  10. X-NNTP-Posting-Host: genesis.demon.co.uk
  11. X-Newsreader: Demon Internet Simple News v1.27
  12. X-Mail2News-Path: genesis.demon.co.uk
  13.  
  14. In article <simmons.821116795@rzdspc1>
  15.            simmons@rzdspc1.informatik.uni-hamburg.de "Geoffrey Simmons" writes:
  16.  
  17. >Thanks to everyone who responded publicly and privately to my post
  18. >"Casting unsigned short as unsigned int -> Bus error" on comp.lang.c
  19. >and gnu.gcc.help. As it turns out, my problem has nothing to do with
  20. >the business about casting, and I suspect it has to do with aligning
  21. >the struct fields of data fetched by the Unix NDBM database library.
  22. >Thus it is probably not a C language problem, which is why I've the changed
  23. >the Subject:, Newsgroups:, and Followup-To: lines.
  24.  
  25. While ndbm isn't part of the C language, your problem seems very much C
  26. language related so I've reinstated comp.lang.c.
  27.  
  28. >        #include <ndbm.h>
  29.  
  30. For the purposes of comp.lang.c assume ndbm.h declares (among other
  31. things) the function dbm_fetch() and the type datum as:
  32.  
  33. typedef struct {
  34.     char *dptr;
  35.     int dsize;
  36. } datum;
  37.  
  38. >        typedef struct {
  39. >                char str1[10];
  40. >                char str2[10];
  41. >                unsigned char c;
  42. >                unsigned short short1;
  43. >                unsigned short short2;
  44. >                time_t mytime;
  45. >                } RecType;
  46. >
  47. >        RecType *MyRec;
  48. >        datum aKey, theDatum;
  49.  
  50. Assume datum is defined by:
  51.  
  52. >        char key[] = "theKey";
  53. >
  54. >        aKey.dptr = &key[0];
  55. >        aKey.dsize = strlen(key) + 1;
  56.  
  57. Did you #include <string.h>?
  58.  
  59. >        theDatum = dbm_fetch(dataFile, aKey);
  60. >        if (theDatum.dptr == NULL)
  61. >            {
  62. >              fprintf(stderr, "Data not found\n");
  63. >              exit(1);                                  /* No error here */
  64. >            }
  65. >        if ((MyRec = (RecType *) malloc(theDatum.dsize)) == NULL)
  66.  
  67. You might as well malloc(sizeof(RecType)) since if theDatum.dsize is not
  68. this value then your code breaks. You might want to test that theDatum.dsize
  69. has the correct value.
  70.  
  71. Did you include stdlib.h or otherwise ensure a declaration for malloc
  72. was in scope? It is a bad idea to cast the return type of malloc in C
  73. since it prevents the compiler warning you about this sort of error.
  74.  
  75. If you don't have a declaraion in scope the compiler assumes that malloc
  76. returns int. An int->RecType * conversion may require a completely different
  77. operation to a void *->RecType * conversion.
  78.  
  79. >            {
  80. >              fprintf(stderr, "Error allocting memory\n");
  81. >              exit(1);                                  /* No error here */
  82. >            }
  83. >        MyRec = (RecType *) theDatum.dptr;
  84.  
  85. You've just gone and thrown away the pointer to your malloc'd block (this is
  86. a memory leak). Maybe you meant to copy the data in the struct in which case
  87. you need instead:
  88.  
  89.          memcpy(MyRec, theDatum.dptr, sizeof(RecType));
  90.  
  91. Don't use:
  92.  
  93.          *MyRec = *(RecType *) theDatum.dptr;
  94.  
  95. because this may assume alignment that is not guaranteed.
  96.  
  97. ...
  98.  
  99. >But when I try to dereference any of the integer-type members, I get bus
  100. >errors:
  101. >
  102. >        unsigned short myshort;
  103. >
  104. >        myshort = MyRec->short1;                        /* Bus error! */
  105. >        myshort = MyRec->short2;                        /* Bus error! */
  106. >        printf("mytime = %ul\n", MyRec->mytime);        /* Bus error! */
  107. >
  108. >I conclude from all this that memory allocation for the struct is not the
  109. >problem, but suspect that the NDBM fetch is not aligning data in memory
  110. >properly (there are warnings about this in the comp.lang.c FAQ and the
  111. >free-databases FAQ).
  112.  
  113. That is not surprising since you were trying to access ndbm's internal
  114. datastructures which know nothing of your alignment requirements. memcpy
  115. to an object with correct alignment as I've noted above.
  116.  
  117. >Is this a well-known problem with NDBM, with a well-known solution? I sure
  118. >hope so.
  119.  
  120. There is nothing in your post that indicates a problem with ndbm, you
  121. just need to fix your code.
  122.  
  123. -- 
  124. -----------------------------------------
  125. Lawrence Kirby | fred@genesis.demon.co.uk
  126. Wilts, England | 70734.126@compuserve.com
  127. -----------------------------------------
  128.